git pull実行時にローカルで未コミットの変更を保持する方法
こんにちは、CX事業本部の若槻です。
git pull
を実行する際に、ローカルで未コミットの変更をリモートに反映させずローカルでだけ保持したい場合があります。
例えば、以下のようにhoge.txt
の変更がローカルで行われていますが、この変更はリモートには反映したくないため、未コミットとしています。
$ cat hoge.txt ローカルでの変更 $ git fetch $ git diff remotes/origin/master diff --git a/hoge.txt b/hoge.txt index 48ee78d..e3130ae 100644 --- a/hoge.txt +++ b/hoge.txt @@ -1 +1 @@ -リモートでの変更 +ローカルでの変更 $ git status On branch master Your branch is behind 'origin/master' by 1 commit, and can be fast-forwarded. (use "git pull" to update your local branch) Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: hoge.txt no changes added to commit (use "git add" and/or "git commit -a")
しかし、この状態でgit pull
をすると以下のようにエラーとなり、プル操作が行えません。
$ git pull origin master From https://github.com/account/test * branch master -> FETCH_HEAD Updating 017abaf..c79d59e error: Your local changes to the following files would be overwritten by merge: hoge.txt Please commit your changes or stash them before you merge. Aborting
対処方法
以下の2通りの対処方法をご紹介します。
- リモートの変更で上書きせず、ローカルでの変更を保持したい場合
- やっぱりリモートの変更で上書きしたくなった場合
リモートの変更で上書きせず、ローカルでの変更を保持したい場合
事前に、ローカルでだけ保持したい変更以外の変更をすべてコミットしておきます。
ローカルでだけ保持したい変更をgit stash
で退避させ、ローカルをクリーンな状態にします。
$ git stash save Saved working directory and index state WIP on master: 017abaf Create hoge.txt $ git status On branch master Your branch is behind 'origin/master' by 1 commit, and can be fast-forwarded. (use "git pull" to update your local branch) nothing to commit, working tree clean
この状態でgit pull
をします。ローカルのhoge.txt
がリモートでの変更で上書きされます。
$ git pull origin master From https://github.com/r-wakatsuki/test * branch master -> FETCH_HEAD Updating 017abaf..c79d59e Fast-forward hoge.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) $ cat hoge.txt リモートでの変更
退避させた変更をstashから戻します。このときhoge.txt
は競合状態となります。
$ git stash apply stash@{0} Auto-merging hoge.txt CONFLICT (content): Merge conflict in hoge.txt $ git status On branch master Your branch is up-to-date with 'origin/master'. Unmerged paths: (use "git reset HEAD <file>..." to unstage) (use "git add <file>..." to mark resolution) both modified: hoge.txt no changes added to commit (use "git add" and/or "git commit -a") $ cat hoge.txt <<<<<<< Updated upstream リモートでの変更 ======= ローカルでの変更 >>>>>>> Stashed changes
競合した変更のうちstashから戻した方の変更を適用します。状態としてはhoge.txt
はまだ競合状態にあります。
$ git checkout --theirs . $ cat hoge.txt ローカルでの変更 $ git status On branch master Your branch is up-to-date with 'origin/master'. Unmerged paths: (use "git reset HEAD <file>..." to unstage) (use "git add <file>..." to mark resolution) both modified: hoge.txt no changes added to commit (use "git add" and/or "git commit -a")
hoge.txt
を一旦ステージングして競合状態を解消します。
$ git add . $ git status On branch master Your branch is up-to-date with 'origin/master'. Changes to be committed: (use "git reset HEAD <file>..." to unstage) modified: hoge.txt
hoge.txt
のステージングを取り消します。これでローカルで未コミットの変更を保持したままgit pull
を行うことができました。
$ git reset HEAD Unstaged changes after reset: M hoge.txt $ git status On branch master Your branch is up-to-date with 'origin/master'. Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: hoge.txt no changes added to commit (use "git add" and/or "git commit -a")
リモートの変更で上書きして良い場合
ローカルで未コミットのまま作業してきた変更を、git pull
時に「やっぱりリモートの変更で上書きしてもいいや」となった場合の対処方法です。
変更を未コミットとしているhoge.txt
に対してチェックアウトを行い、ローカルでの最後のコミット内容を適用してローカルをクリーンにします。
$ git checkout hoge.txt $ git status On branch master Your branch is behind 'origin/master' by 1 commit, and can be fast-forwarded. (use "git pull" to update your local branch) nothing to commit, working tree clean
git pull
を実行してリモートの変更で上書きします。
$ git pull origin master From https://github.com/account/test * branch master -> FETCH_HEAD Updating c79d59e..37b80c5 Fast-forward hoge.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) $ cat hoge.txt リモートでの変更
おわりに
git pull
を実行する際に、ローカルで未コミットの変更に対して
- リモートの変更で上書きせず、ローカルでの変更を保持したい場合
- やっぱりリモートの変更で上書きしたくなった場合
の対処方法についてご紹介しました。
リポジトリに含まれている構成ファイルなどを作業のためにローカルでだけ変更することはよくあるので、覚えておくと役に立ちそうです。どなたかの参考になれば幸いです。
以上